import Vue from "vue";
import VueRouter from "vue-router";
import NProgress from "nprogress";
import { isArray } from "xe-utils";
import store from "@/store/index";
import { getLastPath } from "@/util";
NProgress.configure({ showSpinner: false });
Vue.use(VueRouter);

import Layout from "@/layout";
/*__|ROUTE_IMPORT|__*/

// 当 children 不为空的主导航只有一项时，则隐藏
const constantRoutes = [
  {
    path: "/login",
    name: "login",
    component: () => import(/* webpackChunkName: 'main' */ "@/views/login/login"),
    meta: {
      title: "登录",
    },
  },
  {
    path: "/",
    component: Layout,
    redirect: "/dashboard",
    children: [
      {
        path: "dashboard",
        name: "dashboard",
        component: () => import(/* webpackChunkName: 'main' */ "@/views/index"),
        meta: {
          title: store.state.settings.dashboardTitle,
        },
      },
      {
        path: "reload",
        name: "reload",
        component: () => import(/* webpackChunkName: 'main' */ "@/views/reload"),
      },
    ],
  },
];

const lastRoute = [
  {
    path: "*",
    component: () => import(/* webpackChunkName: 'main' */ "@/views/404"),
    meta: {
      title: "404",
      sidebar: false,
    },
  },
];

let router = new VueRouter({
  routes: constantRoutes,
});
const addRouter = async (to) => {
  //发送请求获取 asyncRoutes
  const asyncRoutes = await store.dispatch("menu/handleRoutes");
  const accessRoutes = await store.dispatch("menu/generateRoutes", {
    asyncRoutes,
    currentPath: to.path,
  });
  accessRoutes.push(...lastRoute);
  accessRoutes.forEach((route) => {
    router.addRoute(route);
  });
};
// 解决路由在 push/replace 了相同地址报错的问题
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch((err) => err);
};
const originalReplace = VueRouter.prototype.replace;
VueRouter.prototype.replace = function replace(location) {
  return originalReplace.call(this, location).catch((err) => err);
};

router.beforeEach(async (to, from, next) => {
  store.state.settings.enableProgress && NProgress.start();
  if (store.getters["user/isLogin"] && !store.state.menu.isGenerate) {
    // 挂载动态路由的同时，根据当前帐号复原固定标签栏
    store.state.settings.enableTabbar && store.commit("tabbar/recoveryStorage", store.state.user.account);
    /**
     * 重置 matcher
     * https://blog.csdn.net/baidu_28647571/article/details/101711682
     */
    router.matcher = new VueRouter({
      routes: constantRoutes,
    }).matcher;
    await addRouter(to);
    next({ ...to, replace: true });
  }
  if (store.state.menu.isUpdataRoute) {
    //有更新
    //重置路由
    router = new VueRouter({
      routes: constantRoutes,
    });
    await addRouter(to);
    store.commit("menu/updataRoutesFinish");
    router.go(0);
    next({ ...to });
  }
  if (store.state.menu.isGenerate) {
    store.commit("menu/setHeaderActived", to.path);
  }
  if (store.getters["user/isLogin"]) {
    const menuData = store.state.menu.menuData;
    if (isArray(menuData) && menuData.length === 0 && to.name == "dashboard") {
      next();
      return;
    }
    if (to.name) {
      if (to.matched.length !== 0) {
        // 如果已登录状态下，进入登录页会强制跳转到控制台页面
        if (to.name == "login") {
          next({
            name: "dashboard",
            replace: true,
          });
        } else if (!store.state.settings.enableDashboard && to.name == "dashboard") {
          // 如果未开启控制台页面，则默认进入第一个固定标签栏或者侧边栏导航第一个模块
          if (store.state.settings.enableTabbar && store.state.tabbar.list.length > 0) {
            next({
              path: store.state.tabbar.list[0].path,
              replace: true,
            });
          } else if (store.getters["menu/sidebarRoutes"].length > 0) {
            next({
              path: getLastPath(store.getters["menu/sidebarRoutes"]),
              replace: true,
            });
          }
        }
      } else {
        // 如果是通过 name 跳转，并且 name 对应的路由没有权限时，需要做这步处理，手动指向到 404 页面
        next({
          path: "/404",
        });
      }
    }
  } else {
    if (to.name != "login") {
      next({
        name: "login",
        query: {
          redirect: to.fullPath,
        },
      });
    }
  }
  next();
});

router.afterEach(() => {
  store.state.settings.enableProgress && NProgress.done();
});

export default router;
